package com.itheima.edu.info.manager.service;

import com.itheima.edu.info.manager.dao.BaseStudentDao;
import com.itheima.edu.info.manager.domain.Option;
import com.itheima.edu.info.manager.domain.Student;
import com.itheima.edu.info.manager.factory.StudentFactory;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;

/*
    业务员类
        1. 这里的所有方法【功能】都是给客服用
        2. 如果某些业务涉及到要对数据仓库的数据进行访问的话,那么需要在业务员类中操作库管对象
        3. 该类的核心作用是用于处理业务逻辑,例如: 判断录入的id是否存在
 */
public class StudentService implements Runnable {

    //持久层对象
    private BaseStudentDao dao = StudentFactory.getStudentDao();
    //服务端套接字对象
    Socket sk;

    //有参构造方法:设置服务端套接字
    public StudentService(Socket sk) {
        this.sk = sk;
    }

    //服务端发送数据到客户端的方法(str)
    public void sendClientData(String str) {
        try {
            //创建一个字符缓冲输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
            //将服务端指定的数据str发送给客户端
            bw.write(str);
            //换行
            bw.newLine();
            //刷新流
            bw.flush();
            //终止字符缓冲输出流
            sk.shutdownOutput();
        } catch (IOException e) {
            System.out.println("sendClientData异常..............");
        } finally {
        }
    }

    //获取客户端发送的数据转换成字符串数组
    public String[] receiveClientData() {
        String[] split = null;
        try {
            //创建字符缓冲输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
            int localPort = sk.getLocalPort();
            //读取客户端发送的数据
            String data = br.readLine();
            //按照指定的格式分割字符串
            split = data.split("&");
            split[2]=String.valueOf(sk.getLocalPort());
        } catch (IOException e) {
            System.out.println("StudentService类getSocketData方法异常...............");
        } finally {
            //返回一个字符串数组
            return split;
        }
    }


    //run方法
    @Override
    public void run() {
        //接收客户端发送的数据,将其按指定格式分割成字符串数组
        String[] split = receiveClientData();
        Option option = Enum.valueOf(Option.class, split[0]);
        switch (option) {
            //判断数组第一个元素是否是login(登录)
            case LOGIN:
                //登录
                login(split[1]);
                break;
            //判断数组第二个元素是否是isExists(判断id是否存在)
            case ISEXISTS:
                isExists(split[1]);
                break;
            //判断数组第三个元素是否是addStudent(添加student对象)
            case ADD:
                addStudent(split[1]);
                break;
            case FIND:
                findAllStudents();
                break;
            case DELETE:
                deleteStudentById(split[1]);
                break;
            case UPDATE:
                updateStudentById(split[1]);
                break;
        }

    }


    //登录功能
    public void login(String str) {
        //获取客户端发送的用户登录信息
        String name = str.split(",")[0];
        String password = str.split(",")[1];
        //获取所有用户的账户信息存储到集合
        Properties prop = dao.findAllUsers();
        //使用标记位,默认登录失败
        boolean flag = false;
        //判断集合是否包含用户登录的账号和密码
        if (prop.containsKey(name) && password.equals(prop.getProperty(name))) {
            flag = true;
        }
        //将登录结果按照指定格式发送给客户端
        sendClientData(flag + "");
    }


    //服务端中的添加学生功能,学生信息的字符串形式(stuStr)
    public void addStudent(String stuStr) {
        //1. 指挥库管把学生对象添加进系统
        //2. 将库管添加的结果再传递给当前类方法的调用者(客服)
        //切割字符串,获取每一个学生对象的属性,并将其构造成一个对象
        String[] split = stuStr.split(",");
        Student stu = new Student(split[0], split[1], split[2], split[3]);
        //返回添加的结果
        boolean flag = dao.addStudent(stu);
        //将添加的结果按照指定格式发送给客户端
        sendClientData(flag + "");
    }

    //服务端判断学号是否存在功能
    public void isExists(String id) {
        //1. 拿到系统中已有的所有学号信息
        // 1.1 指挥库管将系统中所有学生信息查找出来
        ArrayList<Student> allStu = dao.findAllStudents();
        //2. 拿要校验的id去已有的学号中遍历查找
        //2.1 先假设要查找的id不存在
        boolean flag = false;
        //2.2 遍历所有学生信息
        for (int i = 0; i < allStu.size(); i++) {
            //2.3 拿到每一个学生对象的学号
            Student stu = allStu.get(i);
            //2.4 当前索引位置的学生不为null,并且该学生的学号和要查找的学号一致时,修改标记
            if (stu != null && stu.getSid().equals(id)) {
                flag = true;
            }
        }
        sendClientData(flag + "");
    }

    //服务端中的查找所有学生功能
    public void findAllStudents() {
        //获取所有学生对象
        ArrayList<Student> list = dao.findAllStudents();
        //创建发送到客户端的字符串
        //给集合排序
        Collections.sort(list, (stu1, stu2) -> {
            if (stu1 != null & stu2 != null) {
                return stu1.getSid().compareTo(stu2.getSid());
            } else {
                return 0;
            }
        });
        String str = "";
        if (list != null) {
            //拼接所有对象的字符串表示形式
            for (Student student : list) {
                str = str + "=" + student.toString();
            }
            str = str.substring(1);
        }
        //将拼接的字符串发送给客户端
        sendClientData(str);
    }

    //业务员中的删除学生功能
    public void deleteStudentById(String delId) {
        //指挥库管进行删除学生动作
        //获取删除前的对象数量
        int start = dao.findAllStudents().size();
        dao.deleteStudentId(delId);
        //获取删除后的对象数量
        int end = dao.findAllStudents().size();
        //判断删除前和删除后学生对象数量的差别,返回对应的删除结果
        if ((start - end) == 1) {
            sendClientData("true");
        } else {
            sendClientData("false");
        }
    }

    //服务端的修改学生功能
    public void updateStudentById(String newStu) {
        //指挥库管进行修改学生动作
        boolean res = dao.updateStudentById(newStu);
        sendClientData(res + "");
    }
}
